package com.bocloud.cmp.service.resource;

import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.alibaba.fastjson.JSONObject;
import com.bocloud.cmp.dao.CloudVendorDao;
import com.bocloud.cmp.dao.NetworkDao;
import com.bocloud.cmp.dao.PortDao;
import com.bocloud.cmp.dao.RouteDao;
import com.bocloud.cmp.driver.providers.intf.RouterProvider;
import com.bocloud.cmp.entity.resource.CloudVendor;
import com.bocloud.cmp.entity.resource.Network;
import com.bocloud.cmp.entity.resource.Route;
import com.bocloud.cmp.interfaces.resource.RouteService;
import com.bocloud.cmp.model.RouteBean;
import com.bocloud.cmp.model.RouteModel;
import com.bocloud.common.model.BsmResult;
import com.bocloud.common.model.GridBean;
import com.bocloud.common.model.Param;
import com.bocloud.common.model.SimpleBean;
import com.bocloud.common.utils.Common;
import com.bocloud.common.utils.GridHelper;
import com.bocloud.common.utils.JSONTools;
import com.bocloud.common.utils.MapTools;
import com.bocloud.coordinator.harmony.HarmonyLock;
import com.bocloud.coordinator.harmony.LockFactory;
import com.google.common.collect.Maps;

/**
 * 路由Service接口实现
 * 
 * @author dongkai
 *
 */
@Service("routeService")
public class RouteServiceImpl implements RouteService {

    private static Logger logger = LoggerFactory.getLogger(RouteServiceImpl.class);
    @Autowired
    private RouteDao routeDao;
    @Autowired
    private LockFactory lockFactory;
    @Autowired
    private CloudVendorDao cloudVendorDao;
    @Autowired
    private NetworkDao networkDao;
    @Autowired
    private RouterProvider routerProvider;
    @Autowired
    private PortDao portDao;

    @Override
    public BsmResult list(int page, int rows, List<Param> params, Map<String, String> sorter, Boolean simple) {
        List<Route> list = null;
        List<SimpleBean> beans = null;
        int total = 0;
        GridBean gridBean = null;
        try {
            if (null == sorter) {
                sorter = Maps.newHashMap();
            }
            sorter.put("id", Common.ONE);
            total = routeDao.count(params);
            if (simple) {
                beans = routeDao.list(params, sorter);
                gridBean = new GridBean(1, 1, total, beans);
            } else {
                list = this.routeDao.list(page, rows, params, sorter);
                for (Route route : list) {
                    String networkId = route.getNetworkId();
                    if (null != networkId) {
                        Network network = networkDao.getByNetId(networkId);
                        if (null != network) {
                            route.setNetworkName(network.getName());
                        }
                    }
                }
                gridBean = GridHelper.getBean(page, rows, total, list);
            }
            return new BsmResult(true, gridBean, "查询成功");
        } catch (Exception e) {
            logger.error("list route fail:", e);
            return new BsmResult(false, "查询失败", null, null);
        }
    }

    @Override
    public BsmResult create(String params) {
        JSONObject object = JSONTools.isJSONObj(params);
        Long id = object.getLong(Common.ID);
        String name = object.getString(Common.NAME);
        String networkId = object.getString("networkId");
        Boolean adminStateup = object.getBoolean("adminStateup");
        try {
            CloudVendor cloudVendor = cloudVendorDao.query(id);
            if (null == cloudVendor) {
                logger.error("get cloudVendor failure!");
                return new BsmResult(false, "创建失败!");
            }
            Map<String, Object> param = MapTools.simpleMap("name", name);
            param.put("networkId", networkId);
            param.put("adminStateup", adminStateup);
            RouteModel routeModel = JSONObject.parseObject(JSONObject.toJSONString(param), RouteModel.class);
            BsmResult bsmResult = routerProvider.create(routeModel, cloudVendor.getUuid(), null);
            if (null == bsmResult || bsmResult.isFailed()) {
                return new BsmResult(false, "创建失败!");
            }
            Route route = JSONObject.parseObject(JSONObject.toJSONString(bsmResult.getData()), Route.class);
            route.setVendorId(id);
            routeDao.save(route);
            return new BsmResult(true, "创建成功!");
        } catch (Exception e) {
            logger.error("create route failure:", e);
            return new BsmResult(false, "创建失败!");
        }
    }

    @Override
    public BsmResult remove(Long id) {
        String path = Route.class.getSimpleName() + "_" + id;
        HarmonyLock lock = null;
        Boolean result = false;
        try {
            lock = lockFactory.getLock(path);
            if (!lock.acquire(path, 10, TimeUnit.SECONDS)) {
                logger.warn("Get harmonyLock time out!");
                return new BsmResult(false, "请求超时", "", "");
            }
            Route route = routeDao.query(id);
            if (null == route) {
                logger.warn("route data not exist");
                return new BsmResult(false, "数据不存在", "", "");
            }
            // 云供应商
            CloudVendor cloudVendor = cloudVendorDao.query(route.getVendorId());
            if (null == cloudVendor) {
                logger.error("get cloudVendor failure");
                return new BsmResult(false, "删除失败", "", "");
            }
            BsmResult bsmResult = routerProvider.remove(route.getRouteId(), cloudVendor.getUuid(), "");
            if (null == bsmResult || !bsmResult.isSuccess()) {
                return new BsmResult(false, "删除失败");
            }
            result = routeDao.delete(id);
            portDao.removeByDeviceId(route.getRouteId());
        } catch (Exception e) {
            logger.error("remove route fail:", e);
            return new BsmResult(false, "删除失败", "", "");
        } finally {
            if (null != lock) {
                lock.release();
            }
        }
        return result ? new BsmResult(true, "删除成功") : new BsmResult(false, "删除失败", "", "");
    }

    @Override
    public BsmResult detail(Long id) {
        try {
            Route route = routeDao.query(id);
            if (null == route) {
                return new BsmResult(false, "查询详情失败!");
            }
            Long vendorId = route.getVendorId();
            if (null == vendorId) {
                return new BsmResult(false, "查询详情失败!");
            }
            CloudVendor cloudVendor = cloudVendorDao.query(vendorId);
            if (null != cloudVendor) {
                route.setVendorName(cloudVendor.getName());
            }
            return new BsmResult(true, route, "查询成功!");
        } catch (Exception e) {
            logger.error("query route detail failure:", e);
            return new BsmResult(false, "查询详情失败!");
        }
    }

    @Override
    public BsmResult modify(RouteBean bean) {
        String path = Route.class.getSimpleName() + "_" + bean.getId();
        HarmonyLock lock = null;
        BsmResult bsmResult = null;
        try {
            lock = lockFactory.getLock(path);
            if (!lock.acquire(path, 10, TimeUnit.SECONDS)) {
                logger.warn("Get harmonyLock time out!");
                return new BsmResult(false, "请求超时");
            }
            Route route = routeDao.query(bean.getId());
            if (null == route) {
                logger.warn("route data not exist");
                return new BsmResult(false, "数据不存在");
            }
            // 云供应商
            CloudVendor cloudVendor = cloudVendorDao.query(route.getVendorId());
            if (null == cloudVendor) {
                logger.error("get cloudVendor failure");
                return new BsmResult(false, "修改失败", "", "");
            }
            BeanUtils.copyProperties(bean, route);
            RouteModel model = JSONObject.parseObject(JSONObject.toJSONString(route), RouteModel.class);
            model.setRouteId(route.getRouteId());
            bsmResult = routerProvider.modify(model, cloudVendor.getUuid(), "");
            if (null == bsmResult || !bsmResult.isSuccess()) {
                return new BsmResult(false, "修改失败");
            }
            route.setName(bean.getName());
            routeDao.update(route);
            return new BsmResult(true, route, "修改路由成功");
        } catch (Exception e) {
            logger.error("modify route fail:", e);
            return new BsmResult(false, "修改路由失败");
        } finally {
            if (null != lock) {
                lock.release();
            }
        }
    }

}
